package threads;

import java.util.concurrent.ConcurrentLinkedQueue;

import main.Constants;

import tasks.Reportable;
import tasks.TaskList;
import tasks.Taskable;

public class TaskWorker extends Thread {

	private ConcurrentLinkedQueue<TaskList> syncs;
	private Reportable context;
	
	private boolean isStopped;

	public TaskWorker(ConcurrentLinkedQueue<TaskList> syncs, Reportable context){
		this.syncs = syncs;
		this.context = context;
		
		isStopped = true;
	}

	public void pause(){
		this.isStopped = true;
	}
	
	public void startAgain(){
		this.isStopped = false;
	}

	@Override
	public void run() {
		while(true){
			if(isStopped){
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}else{
				//process a TaskList (may block thread)
				TaskList tlist = syncs.poll();
				if(tlist!=null){
					//report game start
					context.reportGameStart(tlist.getGame(), tlist.getTotalSize());
					while(!tlist.isEmpty()){
						Taskable task = tlist.poll();
						if(task!=null){
							int tryEx = task.getTry();
							if(tryEx<=Constants.TRY_COUNT){
								//report task start
								String path = task.getPath();
								long size = task.getSize();
								context.reportFileStart(tlist.getGame(), 
										path, size);
								
								//execute task
								int result = task.start(context);
								
								//report task done
								if(result==0){
									context.reportFileDone(tlist.getGame(), path, size);
								}
								//requeue task if failed
								if(result==-1) tlist.add(task);
							}else{
								System.out.println("Task "+task+" failed!");
							}
						}
					}
					context.reportGameDone(tlist.getGame());
				}
			}
		}
	}
	
}
